//bange_view.cpp
//Copyright (C) 2010-2011 Oscar (.teri) Triano

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include <bange_view.hpp>
#include <bange_scene.hpp>

void bange::view::RegisterVM(lua_State *vm){
	luaL_Reg functions[] = {
	{"NewView", bangeview_NewView},
	{NULL, NULL}};
	luaL_register(vm, NULL, functions);
}

bange::view::view(sf::FloatRect rect, lua_State *vm): sf::View(rect), bange::behavior(vm){
	this->refscene = LUA_REFNIL;
	this->smoothness = 1.0f;
	this->scenewidth = 0.0f;
	this->sceneheight = 0.0f;
	this->newx = 0.0f;
	this->newy = 0.0f;
	this->theview = dynamic_cast<sf::View *>(this);
}

bool bange::view::NewIndex(lua_State *vm){
	//view, key, data
	if (this->bange::behavior::NewIndex(vm)){
		return true;}
	if (strcmp("scene", lua_tostring(vm, 2)) == 0 && lua_isuserdata(vm, 3)){
		bange::scene *scene = dynamic_cast<bange::scene *>(bange::base::GetBaseFromProxy(3, vm));
		if (scene == NULL){
			cout << "bange: view.scene: You can't assign a no scene to a view" << endl;
			return true;}
		luaL_unref(vm, LUA_REGISTRYINDEX, this->refscene);
		this->refscene = luaL_ref(vm, LUA_REGISTRYINDEX);
		return true;
	}
	return false;
}

bool bange::view::Index(lua_State *vm){
	//view, key
	if (this->bange::behavior::Index(vm)){
		return true;}
	if (strcmp("scene", lua_tostring(vm, 2))){
		lua_rawgeti(vm, LUA_REGISTRYINDEX, this->refscene);
		return true;
	}
	return false;
}

void bange::view::CleanVM(lua_State *vm){
	luaL_unref(vm, LUA_REGISTRYINDEX, this->refscene);
}

bange::view::~view(){
	cout << "bange::view destructor for: " << this << endl;
}

static int bangeview_NewView(lua_State *vm){
	//width, height
	sf::FloatRect rect(0.0f, 0.0f, lua_tonumber(vm, 1), lua_tonumber(vm, 2));
	if (rect.Right <= 0 || rect.Bottom <= 0){
		bange::box *box = bange::getbangebox(vm);
		rect.Right = box->GetWidth();
		rect.Bottom = box->GetHeight();
	}
	bange::view *view = new (nothrow) bange::view(rect, vm);
	bange::BuildProxy(LUA_REFNIL, dynamic_cast<bange::base *>(view), vm);
	return 1;
}
